﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OS.Instructions
{
    class CompareRegister : Instruction
    {
        public CompareRegister()
        {
        }//end default constructor

        /// <summary>
        /// Executes the the CR instruction
        /// </summary>
        public override void ExecuteCRInstruction()
        {
            Trace.WriteToTrace("Attempting to execute instruction: " + QueueManager.readyQueue.Peek().register_IR);

            int virtualAddress = int.Parse(QueueManager.readyQueue.Peek().register_IR[2].ToString() + QueueManager.readyQueue.Peek().register_IR[3].ToString());
            int page = virtualAddress / 10;

            if (QueueManager.readyQueue.Peek().TLB.ContainsKey(page))
            {
                //what type is it
                if (QueueManager.readyQueue.Peek().TLB[page] is Frame)
                {
                    int realAddress = UserStorage.VirtualToPhysical(virtualAddress, QueueManager.readyQueue.Peek().register_PTR);
                    String whatsAtTheRealAddress = "";

                    for(int i = 0; i < 4; i++)
                    {
                        whatsAtTheRealAddress += UserStorage.PhysicalMemory[realAddress, i];
                    }

                    Trace.WriteToTrace("Comparing register R = " + CPU.accumulator_R + " to memory location = " + whatsAtTheRealAddress);

                    //check
                    if (CPU.accumulator_R.Equals(whatsAtTheRealAddress))
                    {
                        CPU.toggle_C = true;
                        Trace.WriteToTrace("Toggle C set to true");
                    }
                    else
                    {
                        CPU.toggle_C = false;
                        Trace.WriteToTrace("Toggle C set to false");
                    }

                    CPU.SI = 0;
                }
                else if (QueueManager.readyQueue.Peek().TLB[page] is Track)
                {
                    Track trk = (Track) QueueManager.readyQueue.Peek().TLB[page];
                    
                    //move to swap queue
                    CPU.PI = 3;
                    Trace.WriteToTrace("Need to swap track " + trk.TrackID + " into memory.");
                    Trace.WriteToTrace("Setting PI to 3 to request swap.");
                }
            }
            else
            {
                //invalid page fault
                QueueManager.readyQueue.Peek().terminationType = Termination.InvalidPageFault;
            }

        }//end ExecuteInstruction
    }//end CompareRegister
}//end OS.Instructions
